package com.za.plugin.transfer.form;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 把mysql 的 order by is null asc 变为达梦支持的语法
// https://zhuanlan.zhihu.com/p/526347611
public class OrderByIsNullFormTransfer implements FormTransfer {
    @Override
    public boolean isSupport(String sql) {
        Pattern compile = Pattern.compile("order\\s+by\\s+(.*?)\\s+is\\s+null\\s+(desc|asc)");
        Matcher matcher = compile.matcher(sql.toLowerCase());
        return matcher.find();
    }

    @Override
    public String transfer(String sql) {
        MySqlStatementParser parser = new MySqlStatementParser(sql);
        SQLStatement sqlStatement = parser.parseStatement();
        sqlStatement.accept(new MySqlASTVisitorAdapter() {
            @Override
            public boolean visit(SQLOrderBy expr) {
                for (SQLSelectOrderByItem item : expr.getItems()) {
                    if (item.getExpr() instanceof SQLBinaryOpExpr) {
                        Pattern compile = Pattern.compile("(.*?) IS NULL (ASC|DESC)");
                        Matcher matcher = compile.matcher(SQLUtils.toMySqlString(item));
                        String column = "";
                        String sort = "";
                        if (matcher.find()) {
                            column = matcher.group(1);
                            sort = matcher.group(2);
                            SQLExpr sqlExpr = SQLUtils.toSQLExpr(" case when " + column + " is null or " + column + " ='' then '0' else " + column + " end ");
                            item.setExpr(sqlExpr);
                        }
                    }
                }
                return super.visit(expr);
            }
        });
        return SQLUtils.toMySqlString(sqlStatement).toLowerCase();
    }
}
